<template><div><h2 id="什么是myabtis" tabindex="-1"><a class="header-anchor" href="#什么是myabtis"><span>什么是Myabtis？</span></a></h2>
<p>Mybatis是一款ORM框架，可以让方便开发者在Java对象和数据库之间建立连接，且可以更加方便地存储、检索和操作数据。
Mybatis不会自动地将对象和数据库表进行完全的映射，需要手动配置映射，正是这种方式才能让映射过程更加可控，尤其适用于处理复杂的数据结构。</p>
<p>相比于其他ORM框架，Mybatis更加灵活，它允许开发者直接操控SQL语句，并手动控制对象与数据库表之间的映射关系。</p>
<h2 id="mybatis的优点和缺点是什么" tabindex="-1"><a class="header-anchor" href="#mybatis的优点和缺点是什么"><span>Mybatis的优点和缺点是什么？</span></a></h2>
<h4 id="优点" tabindex="-1"><a class="header-anchor" href="#优点"><span>优点</span></a></h4>
<p>灵活：在XML文件中使用SQL语句来进行编程，这样可以避免和代码或数据库设计产生冲突，也便于集中管理，同时还提供XML标签，用于编写动态地SQL语句。可以重复使用。
方便：相比JDBC，减少了50%的代码，不需要手动来回打开和关闭数据库连接，减轻了开发负担。
兼容性：Mybatis可以很好兼容各种数据库，因为它是基于JDBC连接数据库的。另外，Mybatis还能与Spring集成，给项目开发带来很大的遍历。
映射：Mybatis提供了映射标签，可以很方便地将对象和数据库的字段关系映射起来，方便维护。</p>
<h4 id="缺点" tabindex="-1"><a class="header-anchor" href="#缺点"><span>缺点</span></a></h4>
<p>繁琐：编写SQL语句可能相对繁琐，特别是当涉及多个字段或多个关联表时。
依赖性：由于SQL语句依赖于特定的数据库，移植性就会受到影响。</p>
<h2 id="mybatis与jpa有哪些不同" tabindex="-1"><a class="header-anchor" href="#mybatis与jpa有哪些不同"><span>Mybatis与JPA有哪些不同</span></a></h2>
<p>Mybatis使用了基于SQL的编程模型，开发人员可以精准控制SQL的编写和执行过程。
JPA使用了基于对象的编程模型，开发人员只需要定义实体类并使用注解或XML配置来讲实体映射到数据库表。JPA会自动生成SQL语句，开发人员不需要过多关心底层SQL的实现细节。</p>
<p>灵活性：Mybatis适用于需要定制SQL查询或调用存储过程的场景，比较灵活。JPA则提供了更高多层次的抽象，用于简化常见的数据库操作，但在某些情况也容易产生限制。
查询语言：Mybatis使用原生SQL作为查询语言。JPA引入了JPQL语言，它更加面向对象，类似与SQL，但操作的是实体对象。
缓存：Mybatis的缓存控制更加精细。JPA通常对缓存的控制较少。
学习曲线：Mybatis上手快。JPA由于隐藏了更多细节，需要更多时间理解。</p>
<h2 id="mybatis的核心组件有哪些" tabindex="-1"><a class="header-anchor" href="#mybatis的核心组件有哪些"><span>Mybatis的核心组件有哪些</span></a></h2>
<p><strong>SqlSessionFactory</strong>，会话工厂。它的任务是创建SqlSession对象，这个对象是我们与数据库交互的主要途径，SqlSessionFactory还可以帮我们配置数据库连接信息和事务管理等，一旦这个工厂被建立起来，它就会加载一些必要的配置和映射文件，为后续的数据库操作提供一个可靠的基础。</p>
<p><strong>SqlSession</strong>，可以理解为我们与数据库进行互动的窗口。通过它，我们能够执行SQL语句，提交或回滚事务，还可以获取Mapper接口的实例。不过需要注意的是，SqlSession的生命周期是短暂的，通常在数据库操作完成后就应该关闭它，这样可以释放资源。</p>
<p><strong>Mapper</strong>，这是一个接口，每个Mapper接口对应着一个或多个映射文件，里面的方法定义了具体的SQL操作。Mybatis通过动态代理的方式，把接口方式和映射文件中的SQL语句关联起来，这样我们就可以更加方便通过接口来执行数据库操作。</p>
<p><strong>映射文件</strong>，它是用来连接Java对象和数据库表的桥梁。在映射文件中，可以定义SQL语句、参数映射、结果映射等操作，Mybatis会根据我们调用的方法来选择正确的SQL语句来执行。</p>
<h2 id="mybatis的工作流程是怎么样的" tabindex="-1"><a class="header-anchor" href="#mybatis的工作流程是怎么样的"><span>Mybatis的工作流程是怎么样的</span></a></h2>
<p>配置文件：配置数据库连接、映射文件位置以及一些其他位置。
映射文件：Java对象和数据库表的映射。
SqlSessionFactory：Mybatis读取配置文件和映射文件，创建一个SqlSession实例。
SqlSession：执行数据库操作。
结果映射：通过映射文件中配置的结果映射，解析返回结果。
关闭：关闭SqlSession。</p>
<h2 id="mybatis的一、二级缓存的区别" tabindex="-1"><a class="header-anchor" href="#mybatis的一、二级缓存的区别"><span>Mybatis的一、二级缓存的区别？</span></a></h2>
<h4 id="一级缓存" tabindex="-1"><a class="header-anchor" href="#一级缓存"><span>一级缓存</span></a></h4>
<p>在<strong>同一个会话</strong>中，Mybatis会<strong>自动开启一级缓存</strong>。这个缓存时为了优化查询操作的速度。将查询的结果缓存起来，下次再根据同样的条件查询时，直接从缓存获取，只要当前会话不结束，缓存就一直在这个会话里有效。</p>
<h4 id="二级缓存" tabindex="-1"><a class="header-anchor" href="#二级缓存"><span>二级缓存</span></a></h4>
<p>在<strong>多个会话</strong>中，Mybatis的二级缓存是用来跨会话共享数据的，这样可以减少数据库的访问次数。不过，<strong>二级缓存需要手动配置开启</strong>，它可以把数据存储到更持久的存储地方，例如文件系统。</p>
<h3 id="区别" tabindex="-1"><a class="header-anchor" href="#区别"><span>区别</span></a></h3>
<p>作用范围：一级缓存只有一个会话内部有效，二级缓存可以在不同会话之间共享数据。
开启操作：一级缓存默认是开启的。二级缓存需要手动配置开启。
数据共享性：一级缓存只在一个会话内共享数据，二级缓存可以在不同会话内共享数据。
缓存机制：一级缓存在会话结束时会被清空，二级缓存可以根据一些设置来失效和更新。</p>
<h2 id="mybatis如何处理延迟加载" tabindex="-1"><a class="header-anchor" href="#mybatis如何处理延迟加载"><span>Mybatis如何处理延迟加载？</span></a></h2>
<p>延迟加载：是一种优化方法，为了在查询数据库时，尽量不读取多余的数据，从而提高我们应用的表现和节约资源。在Mybatis中，这个延迟加载的技巧主要用在处理对象关系映射的时候，也就是ORM。</p>
<p>延迟加载的好处：</p>
<ol>
<li>性能更好</li>
<li>节省资源</li>
<li>避免不需要的查询</li>
</ol>
<h2 id="mybatis的动态sql是什么" tabindex="-1"><a class="header-anchor" href="#mybatis的动态sql是什么"><span>Mybatis的动态SQL是什么？</span></a></h2>
<p>动态SQL：可以允许根据不同的条件在运行时构建不同的SQL查询语句。（灵活性高）</p>
<p>在Mybatis中，有<code v-pre>&lt;if&gt;</code>、<code v-pre>&lt;choose&gt;</code>、<code v-pre>&lt;where&gt;</code>等标签来构建动态SQL。</p>
<h2 id="mybatis的xml映射有哪些标签" tabindex="-1"><a class="header-anchor" href="#mybatis的xml映射有哪些标签"><span>Mybatis的XML映射有哪些标签？</span></a></h2>
<ol>
<li><strong>resultMap</strong></li>
<li><strong>association和collection</strong></li>
<li><strong>disciminator</strong></li>
<li><strong>sql</strong></li>
<li><strong>include</strong></li>
<li><strong>if、choose、where、set</strong></li>
<li><strong>trim、where、set</strong></li>
<li><strong>foreach</strong></li>
<li><strong>bind</strong></li>
<li><strong>cache</strong></li>
<li><strong>selectKey</strong></li>
<li><strong>select、insert、update、delete</strong></li>
</ol>
<h2 id="模糊查询like语句该怎么写" tabindex="-1"><a class="header-anchor" href="#模糊查询like语句该怎么写"><span>模糊查询like语句该怎么写？</span></a></h2>
<ol>
<li><strong>字符串拼接方式</strong></li>
</ol>
<div class="language-SQL line-numbers-mode" data-ext="SQL" data-title="SQL"><pre v-pre class="language-SQL"><code>WHERE username LIKE CONCAT('%',#{keyword},'%')
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><ol start="2">
<li><strong>动态SQL方式</strong></li>
</ol>
<div class="language-SQL line-numbers-mode" data-ext="SQL" data-title="SQL"><pre v-pre class="language-SQL"><code>&lt;where&gt;
  &lt;if test=&quot;keyword != null&quot;&gt;
    AND username LIKE CONCAT('%',#{keyword},'%')
  &lt;/if&gt;
&lt;/where&gt;
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="和-的区别是什么" tabindex="-1"><a class="header-anchor" href="#和-的区别是什么"><span>#{}和${}的区别是什么？</span></a></h2>
<p>在Mybatis中，<code v-pre>#{}</code>和<code v-pre>${}</code>都是用于参数替换的标记，用于将参数值插入到SQL语句中。</p>
<ol>
<li><strong>#{}（预编译）</strong></li>
</ol>
<ul>
<li><code v-pre>#{}</code>是用于预编译的参数标记。当使用<code v-pre>#{}</code>时，Mybatis会将参数值放入一个预编译的PreparedStatement中，并确保参数值被正确地转义和应用，从而防止SQL注入攻击。</li>
<li><code v-pre>#{}</code>适用于大多数情况，尤其是当参数值从用户输入中获得时，因为它提供了更好的安全性和可靠性。</li>
</ul>
<ol start="2">
<li><strong>${}（字符串替换）</strong></li>
</ol>
<ul>
<li><code v-pre>${}</code>是用于字符串替换的参数标记。当使用<code v-pre>${}</code>时，Mybatis会直接将参数值嵌入到SQL语句中，不会进行编译或转义。这可能导致潜在的安全问题，如果不正确地处理参数值，可能会导致SQL注入攻击。</li>
<li><code v-pre>${}</code>适用于一些特殊情况，例如在动态表名、列名或函数调用等情况下，但要谨慎使用，确保参数值的安全性。</li>
</ul>
<h2 id="说说mybatis中二级缓存的缺点" tabindex="-1"><a class="header-anchor" href="#说说mybatis中二级缓存的缺点"><span>说说Mybatis中二级缓存的缺点？</span></a></h2>
<ol>
<li><strong>可能出现数据不一致：</strong> 在数据修改后没有及时更新。</li>
<li><strong>内存消耗：</strong> 如果缓存的数据量大，会占用比较多的内存，影响系统性能。</li>
<li><strong>维护成本：</strong> 在更新、删除等操作的时候，需要维护内存。</li>
</ol>
<h2 id="为什么说mybatis是半orm映射工具" tabindex="-1"><a class="header-anchor" href="#为什么说mybatis是半orm映射工具"><span>为什么说Mybatis是半ORM映射工具</span></a></h2>
<p>全ORM框架通常更加自动化，能完全代替你生成SQL语句。
Mybatis可以通过手写SQL实现灵活。</p>
<h2 id="mybatis如何实现动态数据源切换" tabindex="-1"><a class="header-anchor" href="#mybatis如何实现动态数据源切换"><span>Mybatis如何实现动态数据源切换？</span></a></h2>
<ol>
<li><strong>配置文件</strong></li>
<li><strong>AOP切面</strong></li>
<li><strong>AbstractRoutingDataSource</strong></li>
<li><strong>第三方库</strong></li>
</ol>
<h2 id="mybatis如何处理懒加载和预加载" tabindex="-1"><a class="header-anchor" href="#mybatis如何处理懒加载和预加载"><span>Mybatis如何处理懒加载和预加载？</span></a></h2>
<h2 id="说说mybatis的工作原理" tabindex="-1"><a class="header-anchor" href="#说说mybatis的工作原理"><span>说说Mybatis的工作原理</span></a></h2>
<ol>
<li><strong>配置文件</strong></li>
<li><strong>SQL映射文件</strong></li>
<li><strong>SqlSessionFactory</strong></li>
<li><strong>SqlSession</strong></li>
<li><strong>映射器</strong></li>
</ol>
<h2 id="说说mybatis的一、二级缓存" tabindex="-1"><a class="header-anchor" href="#说说mybatis的一、二级缓存"><span>说说Mybatis的一、二级缓存</span></a></h2>
<h2 id="如何在mybatis中进行分页查询" tabindex="-1"><a class="header-anchor" href="#如何在mybatis中进行分页查询"><span>如何在Mybatis中进行分页查询</span></a></h2>
<ol>
<li><strong>PageHelper插件</strong></li>
<li><strong>使用RowBounds</strong></li>
<li><strong>自定义分页插件</strong></li>
</ol>
<h2 id="mybatis的插件能够在哪些地方进行拦截" tabindex="-1"><a class="header-anchor" href="#mybatis的插件能够在哪些地方进行拦截"><span>Mybatis的插件能够在哪些地方进行拦截？</span></a></h2>
<ol>
<li><strong>Executor（执行器）层面的拦截：</strong></li>
<li><strong>StatementHandler（语句处理器）层面的拦截：</strong></li>
<li><strong>ParameterHandler（参数处理器）层面的拦截：</strong></li>
<li><strong>ResultSetHandler（结果集处理器）层面的拦截：</strong></li>
</ol>
<h2 id="如何编写一个mybatis插件" tabindex="-1"><a class="header-anchor" href="#如何编写一个mybatis插件"><span>如何编写一个Mybatis插件？</span></a></h2>
<p>实现Mybatis的<code v-pre>Interceptor</code>接口，并实现<code v-pre>intercept</code>方法，它会在执行SQL语句前后被调用。</p>
<h2 id="简述mybatis的插件运行原理" tabindex="-1"><a class="header-anchor" href="#简述mybatis的插件运行原理"><span>简述Mybatis的插件运行原理</span></a></h2>
<h2 id="mybatis是如何进行分页的。" tabindex="-1"><a class="header-anchor" href="#mybatis是如何进行分页的。"><span>Mybatis是如何进行分页的。</span></a></h2>
<h4 id="mybatis的分页原理" tabindex="-1"><a class="header-anchor" href="#mybatis的分页原理"><span>Mybatis的分页原理：</span></a></h4>
<ol>
<li><strong>数据库方言（Dialect）：</strong></li>
<li><strong>参数传递：</strong></li>
<li><strong>分页处理：</strong></li>
</ol>
</div></template>


